iT邦幫忙

2024 iThome 鐵人賽

0
自我挑戰組

前端工程師的java學習紀錄系列 第 33

Day33-線程Thread(三)

  • 分享至 

  • xImage
  •  

之前在單例模式時有提過,使用懶漢式 的方式在定義單例模式時,有可能會發生線程不安全的問題。

class Bank {
	private static Bank instance;
	private Bank() {}
	
	public static Bank getInstance() {
	
		synchronized(Bank.class) {
			if(instance == null) {
			instance = new Bank();
			}
			return instance;
		}		
	}
}

透過synchronized 可以避免發生多個線程時,創建了兩個Bank 的實例。


線程間的通信指的是,當不同的線程需要共同完成某一項任務時,透過通信的方式,讓他們能夠按照規律的方式執行,而不會產生非預期的狀況發生。

可以透過等待喚醒喚醒全部 三個方法去進行這樣的操作

  • wait() :當線程執行到wait() 時,會進入等待狀態,並且將 釋放。
  • notify() :當線程執行到notify() 時,會喚醒等待 狀態中優先級最高的線程,若優先級相同會隨機喚醒其中一個線程,被喚醒 的線程會從進入等待狀態時的程式碼繼續執行。
  • notifyAll() :當線程執行到notifyAll() 時會喚醒所有等待 狀態中的線程。
// 要使用兩個線程交互印出1-100的數字

class PrintNumber implements Runnable {
	private int number = 1;
	@Override
	public void run() {

		synchronized(this) {
		// 須注意必須和鎖為同一個物件
			this.notify();
			
			while(true) {
				if(number <= 100) {
					System.out.println(Thread.currentThread().getName() + ":" + i);
					number++;
				} else {
					break;
				}
					
				try {
				// 須注意必須和鎖為同一個物件
					this.wait();
				} catch(InterruptedException e) {
					e.printStackTrace();
				}
			}
		}
	}
}

使用這三個方法時需要注意幾個點

  • 必須在synchronized 方法或同步塊中使用。
  • 必須和synchronized 使用的同一個 物件,若不相同會有IllegalMonitorStateException 異常。
  • 這三個方法都是定義在Object 類中。

上一篇
Day32-線程Thread(二)
下一篇
Day34-String
系列文
前端工程師的java學習紀錄41
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言